﻿using Elsa.Extensions;
using Elsa.Features.Services;
using Elsa.Workflows;
using Elsa.Workflows.Middleware.Activities;
using Elsa.Workflows.Middleware.Workflows;
using Elsa.Workflows.Pipelines.ActivityExecution;
using Elsa.Workflows.Pipelines.WorkflowExecution;

namespace ElsaDemo.ActivityWorkflowAop
{
    /// <summary>
    /// ActivityExecMiddleware
    /// </summary>
    public class ActivityExecMiddleware : IActivityExecutionMiddleware
    {
        private readonly ActivityMiddlewareDelegate _next;
        private readonly ILogger<ActivityExecMiddleware> _logger;

        /// <summary>
        /// ctor
        /// </summary>
        public ActivityExecMiddleware(ActivityMiddlewareDelegate next, ILogger<ActivityExecMiddleware> logger)
        {
            _next = next;
            _logger = logger;
        }

        public async ValueTask InvokeAsync(ActivityExecutionContext context)
        {
            _logger.LogInformation("Activity {id} is about to start execution.", context.Activity.Id);
            await _next(context);
            _logger.LogInformation("Activity {id} is about to start execution.", context.Activity.Id);
        }
    }

    /// <summary>
    /// WorkflowExecMiddleware
    /// </summary>
    public class WorkflowExecMiddleware : IWorkflowExecutionMiddleware
    {
        private readonly WorkflowMiddlewareDelegate _next;
        private readonly ILogger<WorkflowExecMiddleware> _logger;

        /// <summary>
        /// ctor
        /// </summary>
        public WorkflowExecMiddleware(WorkflowMiddlewareDelegate next, ILogger<WorkflowExecMiddleware> logger)
        {
            _next = next;
            _logger = logger;
        }

        public async ValueTask InvokeAsync(WorkflowExecutionContext context)
        {
            _logger.LogInformation("Workflow {id} is about to start execution.", context.Workflow.Id);
            await _next(context);
            _logger.LogInformation("Workflow {id} has completed execution.", context.Workflow.Id);
        }
    }


    public static class MiddlewareExtensions
    {
        public static IModule UseWorkflowMiddleware(this IModule builder)
        {
            builder.UseWorkflows(workflow =>
            {
                workflow.WithWorkflowExecutionPipeline(pileline => 
                pileline.UseMiddleware<WorkflowExecMiddleware>().UseExceptionHandling().UseDefaultActivityScheduler()
                
                ); // 
                workflow.WithActivityExecutionPipeline(pileline => pileline.UseMiddleware<ActivityExecMiddleware>().UseDefaultActivityInvoker());
            });

            return builder;
        }
    }
}
